#include "../DataModule.h"

#include <list>

#define NUM_MAP_TSETS	32
#define NUM_TSETS	20
#define NUM_TILES	896

class Subpalette {
  public:
    Color c[16];
    void readFromRom(uint addr, Rom& rom);
    void writeToRom(uint addr, Rom& rom);
    void getAsString(char* out);
    void setAsString(char* str);
};

class Palette {
  private:
    int mtset, mpal;
    int alt_mtset, alt_mpal;
    uint flag;
    uchar spritePal, flashEffect;

    Subpalette subpals[6];

    uint tmpAddr, tmpAltAddr;
  public:
    Palette(int mtset, int mpal);
    Palette(char* str);
    int getMapTileset();
    int getMapPalette();
    void readFromRom(uint start, Rom& rom);
    void writeToRom(uint addr, Rom& rom);
    void getAsString(char* out);
    void setAsString(char* str);

    // Used for reading from ROM
    uint getAddr();
    uint getAltAddr();
    uint getFlag();
    void setAltPal(int mt, int mp);
    int getAltTset();
    int getAltPal();
    uchar getSpritePalette();
    uchar getFlashEffect();

    void setFlag(uint f);
    void setSpritePalette(uchar sp);
    void setFlashEffect(uchar fe);
};

// represents a "graphic"/"drawing" tileset, aka out of 20
class Tileset {
  private:
    std::list<Palette*> pals;
  public:
    uchar tiles[NUM_TILES][8][8];
    uint arrs[1024][4][4];
    uchar collision[1024][4][4];

    void getTileAsStr(int tn, char* out);
    void setTileAsStr(int tn, char* str);

    int getArrsCount();
    void getArrAsStr(int an, char* out);
    void setArrAsStr(int an, char* str);

    void addPalette(int mtset, int mpal, uint start, Rom &rom);
    void addPalette(char* str);
    void clearPalettes();
    std::list<Palette*>* palettesList();
};

class TileModule: public DataModule {
  private:
    Tileset tsets[NUM_TSETS];
  public:
    ~TileModule();
    const char* getName();
    const char* getCredits();

    void readFromRom(Rom& rom);
    void writeToRom(Rom& rom);
    void readFromDat(char* dirName, std::map<std::string, std::string> &fns, std::map<std::string, int> &labels);
    void writeToDat(char* dirName, std::map<std::string, std::string> &fns);
};
